package core.model
{
import com.adobe.utils.DictionaryUtil;

import flash.utils.Dictionary;

import values.item.BuildingItemValue;
import values.item.ItemTemplateValue;
import values.item.ItemTemplateValueList;
import values.item.ItemValue;
import values.item.building.FactoryBuildingItemValue;


/**
 * MapModel
 * @author jliang
 * 
 */
public class MapModel extends ModelBase
{
	//==========================================================================
	//  Constructor
	//==========================================================================
	public function MapModel()
	{
		super();
	}
	//==========================================================================
	//  Variables
	//==========================================================================
	protected var buildings:Dictionary;
	//==========================================================================
	//  Properties
	//==========================================================================
	public function get allBuildings():Array
	{
		return DictionaryUtil.getValues(buildings);
	}
	
	protected var castle:BuildingItemValue;
	
	public function get castleLevel():int
	{
		return castle.level;
	}
	//==========================================================================
	//  Public methods
	//==========================================================================
	public function initCity(data:Object):void
	{
		buildings = new Dictionary(true);
		
		for each (var itemObj:Array in data.building)
		{
			var uid:String = itemObj[0] == "" ? null : itemObj[0];
			var template:ItemTemplateValue = ItemTemplateValueList.getByKey(itemObj[1]);
			var params:Object = itemObj[2];
			var bvo:BuildingItemValue = (ItemValue.create(template, uid,  params)) as BuildingItemValue;
			
			addBuilding(bvo);
			
			if (template.key == "castle")
			{
				castle = bvo;
			}
		}
	}
	//==========================================================================
	//  Public methods
	//==========================================================================
	public function addBuilding(value:BuildingItemValue):void
	{
		buildings[value.uid] = value;
	}
	
	public function removeBuilding(value:BuildingItemValue):void
	{
		delete buildings[value.uid];
	}
    
    public function hasBuilding(value:BuildingItemValue):Boolean
    {
        return buildings[value.uid] == value;
    }
	
    /**
     * building.create(building_uuid, x, y, state, progress, direction) 
     * @param value
     * 
     */    
	public function createBuilding(value:BuildingItemValue):void
	{
		addBuilding(value);
		GameModel.instance.playerModel.removeItem(value);
        
        execute("building_create", 
                      [ value.uid, value.x, value.y, value.state, value.buildProgress, value.direction ], 
                      createBuildingCompleteHander);
	}
    
    protected function createBuildingCompleteHander(data:Object):void
    {
        
    }
    
    /**
     * building.rotate(building_uuid, direction)
     * @param value
     * 
     */    
    public function rotateBuilding(value:BuildingItemValue):void
    {
        execute("building_rotate", 
                     [ value.uid, value.direction ], 
                     rotateBuildingCompleteHander);
    }
    
    protected function rotateBuildingCompleteHander(data:Object):void
    {
        
    }
    
    /**
     * building.move(building_uuid, new_x, new_y)
     * @param value
     * 
     */    
    public function moveBuilding(value:BuildingItemValue):void
    {
        execute("building_move", 
                       [ value.uid, value.x, value.y ], 
                       moveBuildingCompleteHander);
    }
    
    protected function moveBuildingCompleteHander(data:Object):void
    {
        
    }
    
    /**
     * building.stash(building_uuid)
     * @param value
     * 
     */    
    public function stashBuilding(value:BuildingItemValue):void
    {
        value.x = 0;
        value.y = 0;
        removeBuilding(value);
        GameModel.instance.playerModel.addItem(value);
        
        execute("building_stash", 
                      [ value.uid ], 
                      stashBuildingCompleteHander);
    }
    
    protected function stashBuildingCompleteHander(data:Object):void
    {
        
    }
    
    /**
     * item.sell(uuid)
     * @param value
     * 
     */    
    public function sellBuilding(value:BuildingItemValue):void
    {
        removeBuilding(value);
        
        execute("item_sell", 
                      [ value.uid ], 
                      sellBuildingCompleteHander);
    }
    
    protected function sellBuildingCompleteHander(data:Object):void
    {
        
    }
    
    /**
     * building.build(building_uuid, state, progress, cost)
     * @param value
     * 
     */    
    public function buildBuilding(value:BuildingItemValue, cost:Object):void
    {
        removeBuilding(value);
           
        var progress:int = value.buildProgress + 1;
        var state:int = progress >= value.buildCount ? value.state + 1 : value.state;
        
        execute("building_build", 
                      [ value.uid, state, progress, cost ], 
                      buildBuildingCompleteHander);
    }
    
    protected function buildBuildingCompleteHander(data:Object):void
    {
        
    }
    
    /**
     * building.factory_produce(building_uuid, state, product_key, time, cost) 
     * @param value
     * 
     */    
    public function startProduce(value:FactoryBuildingItemValue, state:int, cost:Object):void
    {
        execute("building_factory_produce", 
                     [ value.uid, state, value.currentProduct.key, value.startProduceTime, cost ], 
                     startProduceCompleteHander);
    }
    
    protected function startProduceCompleteHander(data:Object):void
    {
        
    }
    
    /**
     * building.factory_collect(building_uuid, state, cost, bonus) 
     * @param value
     * 
     */    
    public function collectProduct(value:FactoryBuildingItemValue, cost:Object, bonus:Object):void
    {
        execute("building_factory_collect", 
                       [ value.uid, value.state, cost, bonus ], 
                       collectProductCompleteHander);
    }
    
    protected function collectProductCompleteHander(data:Object):void
    {
        
    }
    
    /**
     * building.upgrade(building_uuid, next_level, cost)
     * @param value
     * 
     */    
    public function upgradeBuilding(value:BuildingItemValue, cost:Object):void
    {
        execute("building_upgrade", 
                      [ value.uid, value.level, cost ], 
                      upgradeBuildingCompleteHander);
    }
    
    protected function upgradeBuildingCompleteHander(data:Object):void
    {
        
    }
}
}





